import { NestExpressApplication } from '@nestjs/platform-express';
import { ValidationPipe, BadRequestException } from '@nestjs/common';
import { createZodValidationPipe } from 'nestjs-zod';
import { ZodError } from 'zod';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

/**
 * 企业常见做法：提前自定义一个带统一错误格式的 Zod 管道
 * createZodValidationPipe 会返回一个可实例化的管道类
 */
const GlobalZodValidationPipe = createZodValidationPipe({
	/**
	 * createValidationException:
	 * - 接收到 Zod 抛出的错误对象
	 * - 需要返回一个 Nest 认识的异常（例如 BadRequestException）
	 * 这样 HttpExceptionFilter 才能捕获并输出统一格式
	 */
	createValidationException: error => {
		if (error instanceof ZodError) {
			console.log('🚨 捕获到 Zod 校验错误:', error);
			// 将 Zod 的 issues 数组转成前端更易读的结构
			const formattedErrors = error.issues.map(issue => ({
				field: issue.path.join('.') || '(root)',
				message: issue.message,
				code: issue.code,
			}));

			return new BadRequestException({
				message: 'Zod 参数校验失败',
				errors: formattedErrors,
			});
		}

		// 兜底逻辑：非 ZodError 也统一包装
		return new BadRequestException({
			message: 'Zod 参数校验失败',
			errors: error,
		});
	},
});

export default (app: NestExpressApplication) => {
	// 设置全局查询参数解析器为 'extended'，支持复杂对象的查询参数解析
	app.set('query parser', 'extended');
	// 设置全局管道：包括 Nest 自带的 ValidationPipe 和自定义的 ZodValidationPipe
	app.useGlobalPipes(
		new ValidationPipe({
			whitelist: true, // 自动剔除 DTO 中未定义的属性
			forbidNonWhitelisted: false, // 如果有非法字段，直接报错 比如传了 DTO 中没有的字段 默认不报错
			disableErrorMessages: false, // 启用详细错误消息（生产环境建议设置为 true）
			// 启用类型转换功能，将请求参数转换为 DTO 中定义的类型
			transform: true, // 自动类型转换
			transformOptions: {
				// 转换选项
				enableImplicitConversion: true, // 启用隐式类型转换
			},
		}),
		new GlobalZodValidationPipe(),
	);
	// 设置 Swagger 文档
	const config = new DocumentBuilder().setTitle('Zod API').setVersion('1.0').build();
	const document = SwaggerModule.createDocument(app, config);
	SwaggerModule.setup('api-docs', app, document);
};
